// Only true when the robot is moving backward or forward
var moving = false;
// Only true when the robot is turning while moving
var turning = false;
// Only true when the robot is turning on the spot
var turningOnSpot = false;
// Only true when a connection to the robot has been established by the server
// and verified by the client
var connected = false;
// Used to ensure only 1 ajax request can be sent at a time, others are queued
var requestInProgress = false;
// Identifier for the recurring event reading ajax calls
var updateEventsId;
var baseUrl = "/web/home";

// Do this when the web page is entirely loaded
$(document).ready(function()
{
  bindKeys();
});

/*
 * Call all required binding functions to bind keys to ajax calls
 */
function bindKeys()
{
  bindKeyDownUp();
  bindKeyDownDown();
  bindKeyDownLeft();
  bindKeyDownRight();
//bindKeyUpUp();
//bindKeyUpDown();
//bindKeyUpLeft();
//bindKeyUpRight();
}

/*
 * When 'up' is pressed, tell robot to move forward
 */
function bindKeyDownUp()
{
  $(document).bind('keydown', 'up', function()
  {
    if(connected & !moving & !turning & !turningOnSpot)
    {
      doAction("move_forward");
      moving = true;
    }
    else if(connected)
    {
      doAction("stop");
      doAction("center_turning");
      moving = false;
      turning = false;
      turningOnSpot = false;
    }
  });
}

/*
 * When 'down' is pressed, tell robot to move backward
 */
function bindKeyDownDown()
{
  $(document).bind('keydown', 'down', function()
  {
    if(connected & !moving & !turning & !turningOnSpot)
    {
      doAction("move_backward");
      moving = true;
    }
  });
}

/*
 * When 'left' is pressed, either tell robot to steer left if already moving,
 * or turn left on the spot if not moving
 */
function bindKeyDownLeft()
{
  $(document).bind('keydown', 'left', function()
  {
    if(connected & !turning & !turningOnSpot)
    {
      if(!moving)
      {
        doAction("turn_left_on_spot");
        turningOnSpot = true;
      }
      else if (moving)
      {
        doAction("turn_left");
        turning = true;
      }
    }
    else if(connected & turning)
    {
      doAction("turn_left");
      turning = true;
    }
  });
}

/*
 * When 'right' is pressed, either tell robot to steer right if already moving,
 * or turn right on the spot if not moving
 */
function bindKeyDownRight()
{
  $(document).bind('keydown', 'right', function()
  {
    if (connected & !turning & !turningOnSpot)
    {
      if(!moving)
      {
        doAction("turn_right_on_spot");
        turningOnSpot = true;
      }
      else if (moving)
      {
        doAction("turn_right");
        turning = true;
      }
    }
    else if(connected & turning)
    {
      doAction("turn_right");
      turning = true;
    }
  });
}

/*
 * When 'up' is released, tell robot to stop
 */
function bindKeyUpUp()
{
  $(document).bind('keyup', 'up', function()
  {
    if(connected & moving)
    {
      doAction("stop");
      doAction("center_turning");
      moving = false;
    }
  });
}

/*
 * Get the latest event/sensor readings from the robot and update the web interface
 */
function updateEvents()
{
  $.ajax(
  {
    type: "GET",
    url: baseUrl + "/events_as_json",
    data: "",
    success: function(events)
    {
      var object = eval('{' + events + '}');
      var html = "";
      for(var i=0;i < object.length;i++)
      {
        var event = object[i];
        html += event.eventName + " - " + event.currentReading + event.measurementUnits + "<br />";
      }
      document.getElementById("sensors").innerHTML = html;
    },
    error: function (request, textStatus, errorThrown)
    {
      document.getElementById("messages").innerHTML = request.responseText;
    }
  });
}

/*
 * Remove the event/sensor readings from the web interface
 */
function removeEvents()
{
  document.getElementById("sensors").innerHTML = "not connected to any robot";
}

/*
 * Get a list of all actions for the robot and create a button for each of them
 * on the web interface
 */
function updateActions()
{
  $.ajax(
  {
    type: "GET",
    url: baseUrl + "/actions_as_json",
    data: "",
    success: function(actions, textStatus)
    {
      var object = eval('{' + actions + '}');
      var html = "";
      for(var i=0;i < object.length;i++)
      {
        var action = object[i];
        if (action.type != "default")
        {
          html += "<input type=\"button\" onclick=\"doAction('" + action.safeActionName + "');\" value=\"" + action.actionName + "\" />";
        }
      }
      document.getElementById("actions").innerHTML = html;
    },
    error: function (request, textStatus, errorThrown)
    {
      document.getElementById("messages").innerHTML = request.responseText;
    }
  });
}

/*
 * Remove the action buttons from the web interface
 */
function removeActions()
{
  document.getElementById("actions").innerHTML = "not connected to any robot";
}

/*
 * Tell the server to connect to the robot and if successful, kick of an ajax
 * call at regular interfals to refresh the event/sensor readings
 */
function connect()
{
  document.getElementById("messages").innerHTML = "attempting to connect";
  $.ajax(
  {
    type: "GET",
    url: baseUrl + "/connect",
    data: "",
    success: function(data, textStatus)
    {
      document.getElementById("messages").innerHTML = data;
      connected = true;
      updateEvents();
      updateActions();
      updateEventsId = setInterval(function()
      {
        updateEvents();
      }, 5000);
    },
    error: function (request, textStatus, errorThrown)
    {
      document.getElementById("messages").innerHTML = request.responseText;
    }
  });
}

/*
 * Tell the server to disconnect from the robot and reset all variables and the
 * web interface is successful
 */
function disconnect()
{
  $.ajax(
  {
    type: "GET",
    url: baseUrl + "/disconnect",
    data: "",
    success: function(data, textStatus)
    {
      document.getElementById("messages").innerHTML = data;
      connected = false;
      moving = false;
      turning = false;
      turningOnSpot = false;
      clearInterval(updateEventsId);
      removeEvents();
      removeActions();
    },
    error: function (request, textStatus, errorThrown)
    {
      document.getElementById("messages").innerHTML = request.responseText;
    }
  });
}

/*
 * Tell the server to execute the given action for the robot. If successful, a
 * success message is displayed in the message box
 */
function doAction(name)
{
  while(requestInProgress){}
  requestInProgress = true;
  $.ajax(
  {
    type: "GET",
    url: baseUrl + "/action/" + name,
    data: "",
    success: function(data, textStatus)
    {
      document.getElementById("messages").innerHTML = data;
    },
    error: function (request, textStatus, errorThrown)
    {
      document.getElementById("messages").innerHTML = request.responseText;
    }
  });
  requestInProgress = false;
}
